package utils

import (
	"log"
	"sync"
	"unsafe"
)

/*
**

	放弃使用
*/
type Dispatcher struct {
	lock      *sync.RWMutex
	listeners []*EventCallBack
	dataQueue chan interface{}
	closeWg   sync.WaitGroup
}

type EventCallBack func(data interface{})

func NewDispacher() *Dispatcher {
	rval := &Dispatcher{
		lock:      new(sync.RWMutex),
		listeners: make([]*EventCallBack, 0, 1024),
		dataQueue: make(chan interface{}, 1024),
	}
	return rval
}

// / 添加一个Listener, 返回一个指针，注意移除时需要传入该指针
func (this *Dispatcher) AddListener(callback EventCallBack) *EventCallBack {
	rval := &callback
	this.lock.Lock()
	this.listeners = append(this.listeners, rval)
	this.lock.Unlock()
	return rval
}

// 移除一个Listener, 注意传入的必须是添加时返回的指针
func (this *Dispatcher) RemoveListener(callback *EventCallBack) {
	this.lock.Lock()
	key := -1
	for k, item := range this.listeners {
		a := *(*int)(unsafe.Pointer(item))
		b := *(*int)(unsafe.Pointer(callback))
		if a == b {
			key = k
			break
		}
	}
	if key != -1 {
		this.listeners = append(this.listeners[:key], this.listeners[key+1:]...)
	}
	this.lock.Unlock()
}

// / 分发一次数据
func (this *Dispatcher) dispatchAData(data interface{}) {
	this.lock.RLock()
	defer this.lock.RUnlock()
	for _, cb := range this.listeners {
		(*cb)(data)
	}
}

func (this *Dispatcher) doWorker() {
whilefor:
	for {
		select {
		case data, ok := <-this.dataQueue:
			if ok && data != nil {
				this.dispatchAData(data)
			} else {
				break whilefor
			}
		}
	}
	this.closeWg.Done()
	log.Println("doWorker done")
}

func (this *Dispatcher) Start() {
	this.closeWg.Add(1)
	GoFunc2(this.doWorker)
}

func (this *Dispatcher) Stop() {
	this.dataQueue <- nil
	this.closeWg.Wait()
}

func (this *Dispatcher) Dispatch(data interface{}) {
	this.dataQueue <- data
}
